﻿using System.Runtime.InteropServices;

namespace ZCommon;

public static class CommonFunc
{
    /// <summary>
    /// 将字节数组转换为结构体，只使用结构体需要的数据
    /// </summary>
    /// <typeparam name="T">目标结构体类型</typeparam>
    /// <param name="bytes">源字节数组</param>
    /// <returns>转换后的结构体</returns>
    public static T ByteArrayToStructure<T>(IEnumerable<byte> bytes) where T : struct
    {
        if (bytes == null)
        {
            throw new ArgumentNullException(nameof(bytes));
        }

        int structSize = Marshal.SizeOf(typeof(T));
        if (bytes.Count() < structSize)
        {
            throw new ArgumentException($"字节数组长度({bytes.Count()})小于结构体大小({structSize})");
        }

        // 如果字节数组大于结构体大小，只取前面需要的部分
        byte[] buffer = new byte[structSize];
        Array.Copy(bytes.ToArray(), buffer, structSize);

        GCHandle handle = GCHandle.Alloc(buffer, GCHandleType.Pinned);
        try
        {
            return (T) Marshal.PtrToStructure(handle.AddrOfPinnedObject(), typeof(T))!;
        }
        finally
        {
            handle.Free();
        }
    }


    // 扩展string方法,16进制的字符串转换到byte[]
    public static byte[] HexToBytes(this string hexString, char separator = ' ')
    {
        // 去除首尾空格
        var tempHexString = hexString.Trim();
        if(tempHexString.Length==0)
        {
            return [];
        }
        
        // 按符合分割
        string[] hexParts = tempHexString.Split(separator);
        // 创建byte数组
        byte[] bytes = new byte[hexParts.Length];

        for (int i = 0; i < hexParts.Length; ++i)
        {
            // 如果长度是1（如 "0"），补零变成 "00"
            // string hexByte = hexParts[i].Length == 1 ? "0" + hexParts[i] : hexParts[i];
            // bytes[i] = Convert.ToByte(hexByte, 16);
            bytes[i] = Convert.ToByte(hexParts[i], 16);
        }

        // foreach (byte b in bytes)
        // {
        //     // 输出
        //     Console.Write($"{b:X2} "); 
        // }

        return bytes;
    }

    // 扩展byte[]方法,找到子集序列的索引
    public static int IndexOf(this byte[] source, byte[] sequence)
    {
        return source.AsSpan().IndexOf(sequence);
    }

    // 扩展List<T>方法,找到子集序列的索引
    public static int IndexOf(this List<byte> source, List<byte> sequence)
    {
        return source.ToArray().AsSpan().IndexOf(sequence.ToArray());
    }
}